---
--类名: NodeFactory.lua
--创建日期: 2017-3-20
--创建人: 陈小虎
--功能描述:
--修改内容:
--修改日期:
--修改人:
--修改备注:
--

local NodeFactory = class("NodeFactory")
local NameTitleNode = require("app.world.views.NameTitleNode")

function NodeFactory:ctor()
    self:resetBubbleCount()
end

function NodeFactory:setNodeParent(parent)
	self._nodeParent = parent
end

function NodeFactory:getNodeParent()
	return self._nodeParent
end

function NodeFactory:setNameParent(parent)
    self._nameParent = parent
end

function NodeFactory:getNameParent()
    return self._nameParent
end

function NodeFactory:setUiParent(parent)
    self._uiParent = parent
end

function NodeFactory:getUiParent()
    return self._uiParent
end

function NodeFactory:createMercMark(path,pId,merc)
	if not self:getNodeParent() then return end
    local mark = cc.CSLoader:createNode(path)
    if not mark then
        return
    end
    mark:setCascadeOpacityEnabled(true)
    mark:setAnchorPoint(display.ANCHOR_BOTTOM_CENTER)

    local button = mark:getChildByName("Button")
    if button then
        button:setSwallowTouches(true)
        button:addTouchEventListener(function(sender, eventType)
            if eventType == ccui.TouchEventType.began then
            elseif eventType == ccui.TouchEventType.moved then
            elseif eventType == ccui.TouchEventType.ended then
                local talkStr = FieldManager:getPartnerRandomTalk(pId)
                merc:showBubble(talkStr,3)
            else

            end
        end)
    end
    self:getNodeParent():addChild(mark,1000)
    return mark
end

function NodeFactory:resetBubbleCount()
    self._bubbleCount = 1
end

function NodeFactory:getBubbleCount()
    return self._bubbleCount
end

function NodeFactory:autoRaiseBubbleCount()
    self._bubbleCount = self._bubbleCount + 1
end

function NodeFactory:createBubble(isMerc)
	if not self:getNodeParent() then return end
    local BubbleController = app:getClass("BubbleController")
    local bubble = BubbleController.new()


    if isMerc then
        self:getNodeParent():addChild(bubble,999)
    else
        bubble:setName("bubble_" .. self:getBubbleCount())
        self._uiParent:addChild(bubble,SceneZOrder.storyModeUIOperateZOrder)
        self:autoRaiseBubbleCount()
    end

    return bubble
end

function NodeFactory:clearBubble()
    for i = 1, self:getBubbleCount() do
        local name = "bubble_" .. i
        if self._uiParent:getChildByName(name) then
            self._uiParent:removeChildByName(name)
        end
    end
    self:resetBubbleCount()
end

function NodeFactory:createHeadName()
	if not self:getNameParent() then return end
    local nameNode = NameTitleNode.new()
    self:getNameParent():addChild(nameNode)
    return nameNode
end

function NodeFactory:createStateNode(state)
	if not self:getNodeParent() then return end
    local stateNode = nil
    local nodeAction = nil
    if state == "none" then
    elseif state == "battle" then
        stateNode = cc.CSLoader:createNode(Res.State_InBattle,true)
        nodeAction = cc.CSLoader:createTimeline(Res.State_InBattle)
    elseif state == "fishing" then
        stateNode = cc.CSLoader:createNode(Res.State_Fish,true)
        nodeAction = cc.CSLoader:createTimeline(Res.State_Fish)
    elseif state == "ore" then
        stateNode = cc.CSLoader:createNode(Res.State_Mining,true)
        nodeAction = cc.CSLoader:createTimeline(Res.State_Mining)
    elseif state == "grass" then
        stateNode = cc.CSLoader:createNode(Res.State_Herb,true)
        nodeAction = cc.CSLoader:createTimeline(Res.State_Herb)
    elseif state == "chest" then
        stateNode = cc.CSLoader:createNode(Res.State_Chest,true)
        nodeAction = cc.CSLoader:createTimeline(Res.State_Chest)
    elseif state == "escort" then
    elseif state == "story" then
        stateNode = cc.CSLoader:createNode(Res.State_Story,true)
        nodeAction = cc.CSLoader:createTimeline(Res.State_Story)
    end
    if stateNode then
        if nodeAction then
            stateNode:runAction(nodeAction)
            nodeAction:gotoFrameAndPlay(0,nodeAction:getDuration(),true)
        end
        stateNode:setAnchorPoint(display.ANCHOR_BOTTOM_CENTER)
        self:getNodeParent():addChild(stateNode)
        if BattleManager:isWaitBattle()
            or BattleManager:isBattle()
            or StoryManager:isEnterStoryMode() then
            stateNode:setVisible(false)
        end
    end
    return stateNode
end

function NodeFactory:createMark(path,npc)
	if not self:getNodeParent() then return end
    local mark = cc.CSLoader:createNode(path)
    if not mark then return end

    display.setCascadeColorEnabled(mark,true)
    display.setCascadeOpacityEnabled(mark,true)
    mark:setAnchorPoint(display.ANCHOR_BOTTOM_CENTER)

    local button = mark:getChildByName("Button")
    if button then
        button:setSwallowTouches(true)
        button:addTouchEventListener(function(sender, eventType)
            if eventType == ccui.TouchEventType.began then
            elseif eventType == ccui.TouchEventType.moved then
            elseif eventType == ccui.TouchEventType.ended then
                NpcManager:markClick(npc)
            else

            end
        end)
    end
    self:getNodeParent():addChild(mark,1000)
    return mark
end

-- 创建人物对应的血条 Health_3
function NodeFactory:createCharacterBlood(isEnemy, hp)
    local path 
    if isEnemy then
        path = "ui2/map/state_health_R.csb"
    else
        path = "ui2/map/state_health_B.csb"
    end
    local mark = cc.CSLoader:createNode(path)
    if not mark then return end

    mark:setCascadeOpacityEnabled(true)
    mark:setAnchorPoint(display.ANCHOR_BOTTOM_CENTER)
    mark:getChildByName("Panel"):setVisible(true) -- csd里面把可见性去掉了
    if hp < 3 then
        mark:findChild("Panel/Health_1"):setVisible(false)
    end
    if hp < 2 then
        mark:findChild("Panel/Health_2"):setVisible(false)
    end

    self:getNodeParent():addChild(mark, 1001)
    return mark
end


-- 创建人物对应的血条 跨服工会战
function NodeFactory:createCharacterBlood2(isEnemy, hp)
    local path 
    if isEnemy then
        path = "ui2/map/state_health.csb"
    else
        path = "ui2/map/state_health.csb"
    end
    local mark = cc.CSLoader:createNode(path)
    if not mark then return end

    mark:setCascadeOpacityEnabled(true)
    mark:setAnchorPoint(display.ANCHOR_BOTTOM_CENTER)
    mark:getChildByName("Panel"):setVisible(true) -- csd里面把可见性去掉了

    if hp < 3 then
        mark:findChild("Panel/heart_2"):setVisible(false)
    end
    if hp < 2 then
        mark:findChild("Panel/heart_1"):setVisible(false)
    end
    if hp < 1 then
        mark:findChild("Panel/heart"):setVisible(false)
    end
    
    self:getNodeParent():addChild(mark, 1001)
    return mark
end


-- 创建人物行为图标
function NodeFactory:createCharacterMark(behavior)
    if not self:getNodeParent() then return end

    local path
    if behavior == Enums.behaviorType.battle then
        path = "ui2/map/ani_map_dynasty.csb"
    elseif behavior == Enums.behaviorType.offline then
        path = "ui2/battle/ani_waiting.csb"
    else
        --TODO
    end
    if not path then return end
    local mark = cc.CSLoader:createNode(path)
    if not mark then return end

    mark:setCascadeOpacityEnabled(true)
    mark:setAnchorPoint(display.ANCHOR_BOTTOM_CENTER)

    local timeline = mark:getTimeline()
    if timeline then
        timeline:gotoFrameAndPlay(0, true)
    end
    self:getNodeParent():addChild(mark, 1001)
    return mark
end

-- 创建人物状态buff
function NodeFactory:createCharacterBuff(buff)
    local params
    if buff == "huixue" then
        params = {
            path = Res.ArmatureEffectPath .. "FX_H_Hit01",
            armatureName = "FX_H_Hit01",
            animationName = "doing",
            skeletonName = "FX_H_Hit01"
            
        }
    elseif buff == "defen" then
        params = {
            path = Res.ArmatureBuffPath .. "BUFF_defen",
            armatureName = "BUFF_defen",
            animationName = "effloop",
            skeletonName = "BUFF_defen"
        }
    end

    if not params then return end

    local Armature = app:getClass("Armature")
    local armature = Armature.create(params)
    armature:play(params.animationName, 10000) -- 循环播放暂时有bug，这里填一个比较大的次数

    -- self:getNodeParent():addChild(armature, 1002)
    return armature
end

-- 创建主线任务 人物特效
function NodeFactory:createCharacterMainTaskBuff(buffName)
    local info = Enums.mainTaskEffect[buffName]
    if not info then return end
    local params = {
        path = Res.ArmatureBuffPath .. info.armatureName,
        armatureName = info.armatureName,
        animationName = info.animationName,
        skeletonName = info.armatureName
    }

    local Armature = app:getClass("Armature")
    local armature = Armature.create(params)
    armature:play(params.animationName, 10000) -- 循环播放暂时有bug，这里填一个比较大的次数

    return armature
end

function NodeFactory:createLevelUpAnimation()
    local Armature = app:getClass("Armature")
    local levelUpAnimation = Armature.create({
        path = Res.Effect_LevelUp.dir,
        armatureName = Res.Effect_LevelUp.name,
        animationName = "",
        skeletonName = Res.Effect_LevelUp.name
        })
    return levelUpAnimation
end

function NodeFactory:createEquipAnimation(location, job)
    local Armature = app:getClass("Armature")
    local param
    if location == 1 then   -- 主手
        param = Res.Effect_Equip_Main_Weapon[job]
    else
        param = Res.Effect_Equip_Location[location]
    end

    if param then
        local ani = Armature.create({
            path = param.dir,
            armatureName = param.name,
            skeletonName = param.name
        })
        return ani
    else
        return nil
    end
end

function NodeFactory:createEquipCommonAnimation(index)
    local Armature = app:getClass("Armature")
    local param = Res.Effect_Equip_Common[index]

    if param then
        local ani = Armature.create({
            path = param.dir,
            armatureName = param.name,
            skeletonName = param.name
        })
        return ani
    else
        return nil
    end
end

function NodeFactory:createBattleMark()
    local Armature = app:getClass("Armature")
    local battleMarkNode = Armature.create({
        path = Res.Effect_Battle_Gantanhao.dir,
        armatureName = Res.Effect_Battle_Gantanhao.name,
        animationName = "",
        skeletonName = Res.Effect_Battle_Gantanhao.name,
        textureName = Res.Effect_Battle_Gantanhao.name
    })
    local action = Res.Effect_Battle_Gantanhao.name
    return battleMarkNode,action
end

function NodeFactory:createGuideAnimation(resFinger,desc,times,arrowDir)
    if not self:getNodeParent() then return end
    local Armature = app:getClass("Armature")
    local animation = Armature.create({
        path = resFinger.dir,
        armatureName = resFinger.name,
        animationName = "",
        skeletonName = resFinger.name,
        textureName = resFinger.name
    })
    if animation then
        if times > 0 then
            animation.times = times
        end
        local scaleX = 1
        if arrowDir == "d" or arrowDir == "r" then
            scaleX = 1
        elseif arrowDir == "l" then
            scaleX = -1
        end
        animation:setScaleX(scaleX)
        self:getNodeParent():addChild(animation,1001)
        animation:playAni({name = resFinger.action})
        return animation
    end
    return nil
end

function NodeFactory:createArrowAnimation(resFinger,pos,desc,taskId,times,arrowDir)
    if not self.m_Arrow then
        self.m_Arrow = {}
        self.m_Arrow.taskId = taskId
        self.m_Arrow.arrowAnimation = self:createGuideAnimation(resFinger,"",times)
        if self.m_Arrow.arrowAnimation then
            local scaleX = 1
            if arrowDir == "d" or arrowDir == "r" then
                scaleX = 1
            elseif arrowDir == "l" then
                scaleX = -1
            end
            self.m_Arrow.arrowAnimation:setScaleX(scaleX)
            self.m_Arrow.arrowAnimation:setPosition(pos)
            if desc then
                if StoryManager:isEnterStoryMode() then
                    self.m_Arrow.arrowAnimation:setVisible(false)
                end
            end
        end
    end
end

function NodeFactory:deleteArrowAnimation()
    if self.m_Arrow and self.m_Arrow.arrowAnimation and self:getNodeParent() then
        self:getNodeParent():removeChild(self.m_Arrow.arrowAnimation)
    end
    self.m_Arrow = nil
end

function NodeFactory:updateArrowAnimationTimes()
    if self.m_Arrow and self.m_Arrow.arrowAnimation then
        if self.m_Arrow.arrowAnimation.times then
            self.m_Arrow.arrowAnimation.times = self.m_Arrow.arrowAnimation.times - 1
            if self.m_Arrow.arrowAnimation.times == 0 then
                self:deleteArrowAnimation()
            end
        end
    end
end

function NodeFactory:arrowAnimationViewing(visible,taskId)
    if self.m_Arrow and self.m_Arrow.arrowAnimation then
        if visible then
            if self.m_Arrow.taskId ~= taskId then
                self.m_Arrow.arrowAnimation:setVisible(visible)
            end
        else
            self.m_Arrow.arrowAnimation:setVisible(visible)
        end
    end
end

return NodeFactory


